﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Windows;
using Caliburn.Micro;
using PurchaseSales.Manage.Model.Entities;
using PurchaseSales.Manage.Services;
using ReactiveUI;
using ReactiveUI.Xaml;

namespace PurchaseSales.Manage.ViewModels
{
    public class SalesViewModel : Screen
    {
        private readonly ISalesRepository _salesRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly ICommodityRepository _commodityRepository;
        private readonly IPurchaseCommodityRepository _purchaseCommodityRepository;
        private double _remainCount;
        private double _buyCount;

        public IList<Customer> Customers { get; set; }
        public IList<Commodity> Commodities { get; set; }
        public IList<PurchaseCommodity> PurchaseCommodities { get; set; }

        public ReactiveCommand DeletedCommand { get; set; }
        public ReactiveCommand AddCommand { get; set; }
        public ReactiveAsyncCommand SelectedCustomerCommand { get; set; }
        public ReactiveAsyncCommand SelectedCommodityCommand { get; set; }
        public ReactiveCollection<Sales> Saleses { get; set; }
        private ObservableAsPropertyHelper<Commodity> _selectedCommodity;
        private ObservableAsPropertyHelper<Customer> _selectedCustomer;

        public SalesViewModel(ISalesRepository salesRepository, ICustomerRepository customerRepository, ICommodityRepository commodityRepository, IPurchaseCommodityRepository purchaseCommodityRepository)
        {
            _salesRepository = salesRepository;
            _customerRepository = customerRepository;
            _commodityRepository = commodityRepository;
            _purchaseCommodityRepository = purchaseCommodityRepository;

            SelectedCustomerCommand = new ReactiveAsyncCommand();
            var customerObservable = SelectedCustomerCommand.RegisterAsyncFunction(o => o as Customer);
            _selectedCustomer=new ObservableAsPropertyHelper<Customer>(customerObservable,_=>{});

            SelectedCommodityCommand = new ReactiveAsyncCommand();
            var commodityObservable = SelectedCommodityCommand.RegisterAsyncFunction(o =>
                            {
                                var commodity = o as Commodity;
                                var purchaseCommodity = PurchaseCommodities.FirstOrDefault(x => x.Commodity == commodity);
                                if (purchaseCommodity != null)
                                    RemainCount = purchaseCommodity.Count;
                                else
                                    RemainCount = 0d;
                                return commodity;
                            });
            _selectedCommodity=new ObservableAsPropertyHelper<Commodity>(commodityObservable,_=>{});
            var latest = Observable.CombineLatest(customerObservable, commodityObservable, (customer, commodity) => { return customer != null && commodity != null; }).StartWith(false);
            AddCommand = new ReactiveCommand(latest);
            AddCommand.Subscribe(o =>
                                     {
                                         var sales = new Sales();
                                         sales.Number = Number;
                                         sales.Count = BuyCount;
                                         sales.Commodity = _selectedCommodity.Value;
                                         sales.Customer = _selectedCustomer.Value;
                                         sales.Remark = Remark;
                                         sales.SaleDate = DateTime.Now;
                                         sales.TotalPrice = _selectedCommodity.Value.PresalePrice*(decimal)BuyCount;
                                         _salesRepository.MakePersistent(sales);
                                         _salesRepository.Commit();

                                         Saleses.Add(sales);
                                     });
         
            DeletedCommand = new ReactiveCommand();
            DeletedCommand.Subscribe(o =>
                                         {
                                             var sales = o as Sales;

                                             _salesRepository.MakeTransient(sales);
                                             _salesRepository.Commit();

                                             Saleses.Remove(sales);
                                         });

        }

        protected override void OnInitialize()
        {
            var saleses = _salesRepository.GetAll();
            Saleses = saleses.ToObservable().CreateCollection();
            Commodities = _commodityRepository.GetAll();
            Customers = _customerRepository.GetAll();
            PurchaseCommodities = _purchaseCommodityRepository.GetAll();
        }

        public double RemainCount
        {
            get { return _remainCount; }
            set { _remainCount = value; NotifyOfPropertyChange(() => RemainCount); }
        }

        private string _remark;
        public string Remark
        {
            get { return _remark; }
            set { _remark = value; NotifyOfPropertyChange(() => Remark); }
        }

        private string _number;
        public string Number
        {
            get { return _number; }
            set { _number = value; NotifyOfPropertyChange(() => Number); }
        }

        public double BuyCount
        {
            get { return _buyCount; }
            set { _buyCount = value; NotifyOfPropertyChange(() => BuyCount); }
        }
    }
}
